package com.sumer.psychology.common.event;

import com.sumer.psychology.common.domain.model.DomainEvent;
import com.sumer.psychology.common.domain.model.DomainEventPublisher;
import com.sumer.psychology.common.domain.model.DomainEventSubscriber;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import javax.inject.Inject;

/**
 * 记录所有Event的AOP程序
 * <p/>
 * User: zhenguang.zhu
 * Date: 2014/8/20
 * Time: 10:13
 */
@Aspect
public class EventProcessor {
    private EventStore eventStore;

    @Inject
    public EventProcessor(EventStore eventStore) {
        super();
        this.eventStore = eventStore;
    }

    /**
     * 不使用AOP时的静态替换方法
     *
     * @param eventStore event store
     */
    public static void register(EventStore eventStore) {
        new EventProcessor(eventStore).listen();
    }

    @Before("execution(* com.sumer.psychology..*application.command..*ApplicationService.*(..))")
    public void listen() {
        DomainEventPublisher.instance().reset();

        DomainEventPublisher
                .instance()
                .subscribe(new DomainEventSubscriber<DomainEvent>() {
                    @Override
                    public void handleEvent(DomainEvent aDomainEvent) {
                        store(aDomainEvent);
                    }

                    @Override
                    public Class<DomainEvent> subscribedToEventType() {
                        return DomainEvent.class; // all domain events
                    }
                });
    }

    /**
     * Stores aDomainEvent to the event store.
     *
     * @param aDomainEvent the DomainEvent to store
     */
    private void store(DomainEvent aDomainEvent) {
        this.eventStore().append(aDomainEvent);
    }

    /**
     * Answers my EventStore.
     *
     * @return EventStore
     */
    private EventStore eventStore() {
        return this.eventStore;
    }
}
